package com.heiye.oss.biz.strategy.impl;

import com.heiye.framework.common.exception.BizException;
import com.heiye.oss.biz.config.MinioProperties;
import com.heiye.oss.biz.enums.ResponseCodeEnum;
import com.heiye.oss.biz.strategy.FileStrategy;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.util.UUID;

/**
 * @author: heiye
 * @date: 2024/11/21 下午1:32
 * @version: v1.0.0
 * @description: TODO
 */
@Slf4j
public class MinioFileStrategy implements FileStrategy {

    @Resource
    private MinioProperties minioProperties;

    @Resource
    private MinioClient minioClient;

    /**
     * 用户头像上传
     *
     * @param avatar
     * @param bucketName
     * @return
     */
    @Override
    @SneakyThrows
    public String uploadAvatar(MultipartFile avatar, String bucketName) {
        log.info("## 用户头像上传至 Minio ...");

        // 判断文件是否为空
        if (avatar == null || avatar.getSize() == 0) {
            log.error("==> 上传用户头像异常：文件大小为空...");
            throw new BizException(ResponseCodeEnum.FILE_SIZE_EMPTY);
        }

        // 文件的原始名称
        final String originalFilename = avatar.getOriginalFilename();
        // 文件的 Content-type
        String contentType = avatar.getContentType();

        // 生成存储对象的名称(将 UUID 字符串中的 - 替换成空字符串)
        String key = UUID.randomUUID().toString().replace("-", "");
        // 获取文件的后缀，如 .jpg
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        // 拼接上用户头像后缀，即为要存储的用户头像名
        String objectName = String.format("%s%s", key, suffix);

        log.info("==> 开始上传文件至 Minio, objectName: {}", objectName);

        // 上传文件至 Minio
        minioClient.putObject(PutObjectArgs
                .builder()
                .bucket(bucketName)
                .object(objectName)
                .stream(avatar.getInputStream(), avatar.getSize(), -1)
                .contentType(contentType)
                .build());

        // 返回文件的访问链接
        String url = String.format("%s/%s/%s", minioProperties.getEndpoint(), bucketName, objectName);

        log.info("==> 上传用户头像至 Minio 成功, 访问路径：{}", url);

        return url;
    }
}
